/*
 *  Jun 16, 2009
 */
package app;

import java.util.Calendar;
import java.util.Date;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Gauge;
import javax.microedition.lcdui.StringItem;
import javax.microedition.media.Manager;
import javax.microedition.media.Player;
import javax.microedition.media.control.RecordControl;
import javax.wireless.messaging.Message;
import javax.wireless.messaging.MessageConnection;
import javax.wireless.messaging.MessageListener;
import javax.wireless.messaging.MessagePart;
import javax.wireless.messaging.MultipartMessage;
import javax.wireless.messaging.TextMessage;

/**
 *
 * @author thirdy
 */
public class ThesisServer implements ThesisMessageReceiver {

    private MessageConnection SMSServer;
    private MessageConnection MMSServer;
    private ThesisMessageReader thesisMessageReader;
    private Form thesisServerLog;
    private Player player;
    private String pathLastVideo;
    private RecordControl recordControl = null;
    private String clientNum;
    private String videoFldrPath;
    private ThesisMIDlet thesisMIDlet;
    private FileConnection recFc;
    private String lastServerError;
    private String mmsSubject = "Thesis MMS";
    private boolean allowRequest = true;

    ThesisServer(Form ThesisServerLog, final ThesisMIDlet thesisMIDlet) {
        this.thesisMIDlet = thesisMIDlet;
        this.thesisServerLog = ThesisServerLog;

        new Thread(new Runnable() {

            public void run() {
                log("Starting..");
                try {                    
                    //#if PHONE!="EMULATOR"
                    videoFldrPath = System.getProperty("fileconn.dir.memorycard");
                    if (videoFldrPath == null) {
                        videoFldrPath = System.getProperty("fileconn.dir.videos");
                        if (videoFldrPath == null) {
                            throw new Exception("Problem with storage");
                        }
                    }

                    String vidsupport = System.getProperty("supports.video.capture");
                    if (vidsupport == null || vidsupport.equals(ThesisConstants.EMPTY) || vidsupport.equals("false")) {
                        throw new Exception("Video recording not supported: " + vidsupport);
                    }
                    log("Video folder: " + videoFldrPath);
                    //#endif
                    // WMA
                    if (thesisMIDlet.isStartedByReq()) {
                        SMSServer = thesisMIDlet.getSMSServer();
                    } else {
                        SMSServer = (MessageConnection) Connector.open("sms://:" + ThesisConstants.SMSPORT);
                    }
                    MMSServer = (MessageConnection) Connector.open("mms://:" + ThesisConstants.APPID);
                    thesisMessageReader = new ThesisMessageReader(SMSServer, ThesisServer.this);
                    SMSServer.setMessageListener(new MessageListener() {

                        public void notifyIncomingMessage(MessageConnection conn) {
                            if (allowRequest) {
                                log("AllowRequest: " + allowRequest);
                                thesisMessageReader.handleMessage();
                            }else {
                                log(ThesisConstants.REQUEST_RECEIVED_WHILE_AUTO);
                            }
                        }
                    });
                    if (SMSServer == null || MMSServer == null) {
                        throw new Exception("SMS/MMS Server failed to start");
                    }
                    if (thesisMIDlet.isStartedByReq()) {
                        thesisMessageReader.handleMessage();
                        thesisMIDlet.setStartedByReq(false);
                    }
                } catch (Throwable t) {
                    log(t);
                    log("Server failed to start.");
                    return;
                }
                new Thread(thesisMessageReader).start();
                log("Server successfully started.");
            }
        }).start();
    }

    public void destroy() {
        try {
            if (SMSServer != null) {
                SMSServer.close();
            }
            if (MMSServer != null) {
                MMSServer.close();
            }
            if (thesisMessageReader != null) {
                thesisMessageReader.close();
            }
        } catch (Throwable t) {
            log(t);
        }
        SMSServer = null;
        MMSServer = null;
        thesisMessageReader = null;
    }

    public void messageReceived(Message mess) {
        TextMessage textMessage = (TextMessage) mess;
        clientNum = getNumberFromSMSAdd(mess.getAddress());
        System.out.println("Adress: " + clientNum);
        final String msg = textMessage.getPayloadText();
        thesisServerLog.append("SMS Received: " + msg);
        sendNotification(ThesisConstants.IDX_CONFIRM_RECIV_REQ);
        boolean successPlayer = initPlayer();
        if (!successPlayer) {
            sendNotification(ThesisConstants.IDX_SERVER_ERRORS);
            return;
        }
        if (msg.equals(ThesisConstants.REC3SEC)) {
            doRecord(10);
        }
        if (msg.equals(ThesisConstants.REC5SEC)) {
            doRecord(20);
        }
        if (msg.equals(ThesisConstants.REC10SEC)) {
            doRecord(30);
        }

    }

    public boolean initPlayer() {
        //#if PHONE != "EMULATOR"
        if (player == null) {
            try {
                // Creates and initializes a player for video record
                //#if PHONE == "NOKIA"
//#                 player = Manager.createPlayer("capture://video");
                //#elif PHONE == "SONYERICSSON"
//#                 player = Manager.createPlayer("capture://audio_video");
                //#endif
                player.start();
            } catch (Throwable t) {
                log(t);
                return false;
            }
            recordControl = (RecordControl) player.getControl("RecordControl");

            if (recordControl == null) {
                log(new Exception("No Supported Control Found"));
                return false;
            }
        }
        //#endif
        return true;
    }

    private Gauge sendMMSGauge = new Gauge(ThesisConstants.EMPTY, false, Gauge.INDEFINITE, Gauge.CONTINUOUS_RUNNING);

    public void doRecord(int sec) {
        try {
            sendMMSGauge.setLabel("Recording..");
            thesisServerLog.append(sendMMSGauge);
            //#if PHONE != "EMULATOR"
            pathLastVideo = videoFldrPath + getFileNameForVid() + ".3gp";
            recordControl.setRecordLocation(pathLastVideo);
            recordControl.startRecord();
            //#endif
            Thread.sleep(sec * 1000);
            //#if PHONE != "EMULATOR"
            recordControl.commit();
            //#endif
            log("Recording Success");
            sendMMSGauge.setLabel("Sending MMS..");
            //#if PHONE != "EMULATOR"
            player.close();
            player = null;
            MultipartMessage mms = (MultipartMessage) MMSServer.newMessage(MessageConnection.MULTIPART_MESSAGE);
            mms.setSubject(mmsSubject);
            recFc = (FileConnection) Connector.open(pathLastVideo, Connector.READ_WRITE);
            MessagePart video = new MessagePart(recFc.openInputStream(), "video/3gpp", "video1", "video", null);
            mms.addMessagePart(video);
            mms.setAddress("mms://" + clientNum);
            MMSServer.send(mms);
            sendNotification(ThesisConstants.IDX_CONFIRM_MMS_SENT);
            //#endif
            thesisServerLog.delete(thesisServerLog.size()-2);
            log("MMS sent to: " + clientNum);
        } catch (Throwable t) {
            log(t);
            sendNotification(ThesisConstants.IDX_SERVER_ERRORS);
        } finally {
            // do delete
           //#if PHONE != "EMULATOR"
            try {
                if (!thesisMIDlet.isSaveRecsFlag()) {
                    recFc.delete();
                    if (!recFc.exists()) {
                        log("File deleted: " + getFileNameForVid());
                    }
                }
                recFc.close();
            } catch (Throwable t) {
                log(t);
                sendNotification(ThesisConstants.IDX_SERVER_ERRORS);
            }
             //#endif
        }
    }

    private String getNumberFromSMSAdd(
            String address) {
        address = address.substring(6);
        String s = "";
        for (int i = 0; i <
                address.length(); i++) {
            if (address.charAt(i) == ':') {
                break;
            }

            s += address.charAt(i);
        }

        return s;
    }

    private void log(Throwable t) {
        t.printStackTrace();
        lastServerError = t.getMessage();
        log(t.getMessage());
    }

    private void log(String s) {
        s = s + "\n";
        StringItem si = new StringItem(null, s);
//        si.setLayout(Item.LAYOUT_NEWLINE_AFTER);
        thesisServerLog.append(s);
    }

    public synchronized void sendSMS(String message, String address) {
        final TextMessage textMessage = (TextMessage) SMSServer.newMessage(MessageConnection.TEXT_MESSAGE);
        textMessage.setPayloadText(message);
        textMessage.setAddress("sms://" + address + ":" + ThesisConstants.SMSPORT);
        System.out.println(textMessage.getAddress());
        new Thread() {

            public void run() {
                try {
                    SMSServer.send(textMessage);

                } catch (Throwable t) {
                    log(t);
                }

            }
        }.start();
    }

    private void sendNotification(int settingIDX) {
        if (thesisMIDlet.getSrvrSettingsFlag()[settingIDX] && ThesisConstants.IDX_CONFIRM_RECIV_REQ == settingIDX) {
            sendSMS(ThesisConstants.CONFIRM_REQ_RECIV_MSG, clientNum);
        }

        if (thesisMIDlet.getSrvrSettingsFlag()[settingIDX] && ThesisConstants.IDX_CONFIRM_MMS_SENT == settingIDX) {
            sendSMS(ThesisConstants.CONFIRM_MMS_SENT_MSG, clientNum);
        }

        if (thesisMIDlet.getSrvrSettingsFlag()[settingIDX] && ThesisConstants.IDX_SERVER_ERRORS == settingIDX) {
            sendSMS(ThesisConstants.CONFIRM_SERVER_ERRORS_MSG + ": " + lastServerError, clientNum);
        }
    }

    private String getFileNameForVid() {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());

        int year = calendar.get(Calendar.YEAR);
        int month = calendar.get(Calendar.MONTH);
        int day = calendar.get(Calendar.DAY_OF_MONTH);
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);

        return new String(thesisMIDlet.getFileNamePrefix() + month + "-" + day + "_" + hour + "-" + minute); // + "-" + second);
    }

    public void setClientNum(String clientNum) {
        this.clientNum = clientNum;
    }

    public void setMmsSubject(String mmsSubject) {
        this.mmsSubject = mmsSubject;
    }

    public void setAllowRequest(boolean b) {
        allowRequest = b;
    }
}
